package com.whfc.fse.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.whfc.common.enums.HandleFlag;
import com.whfc.common.exception.BizException;
import com.whfc.common.result.ListData;
import com.whfc.common.result.PageData;
import com.whfc.common.result.ResultEnum;
import com.whfc.common.util.PageUtil;
import com.whfc.entity.dto.msg.AppMsgToUserDTO;
import com.whfc.entity.dto.warn.AppWarnRuleDTO;
import com.whfc.entity.param.warn.AppWarnHandleParam;
import com.whfc.fse.dao.*;
import com.whfc.fse.dto.*;
import com.whfc.fse.entity.*;
import com.whfc.fse.enums.FseType;
import com.whfc.fse.enums.FseWarnRuleType;
import com.whfc.fse.param.FseWarnSetUserParam;
import com.whfc.fse.param.WarnBatchDelParam;
import com.whfc.fse.param.WarnBatchHandleParam;
import com.whfc.fse.service.FseWarnService;
import com.whfc.fuum.entity.SysUser;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

/**
 * @author GuoDong_Sun
 * @date 2020/4/13
 */
@DubboService(interfaceClass = FseWarnService.class, version = "1.0.0", timeout = 30 * 1000)
public class FseWarnServiceImpl implements FseWarnService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private FseWarnMapper fseWarnMapper;

    @Autowired
    private FseWarnRuleMapper fseWarnRuleMapper;

    @Autowired
    private FseWarnRuleUserMapper fseWarnRuleUserMapper;

    @Autowired
    private FseWarnRuleChannelMapper fseWarnRuleChannelMapper;

    @Autowired
    private FseCraneMapper fseCraneMapper;

    @Autowired
    private FseLiftMapper fseLiftMapper;

    @Autowired
    private FseBridgeMapper fseBridgeMapper;

    @Autowired
    private FseGantryMapper fseGantryMapper;

    @Autowired
    private FseCrawlerMapper fseCrawlerMapper;

    @Override
    public ListData<AppWarnRuleDTO> ruleList(Integer deptId, Integer type) {
        logger.info("特种设备的报警规则列表服务,deptId:{},type:{}", deptId, type);
        List<AppWarnRuleDTO> list = fseWarnRuleMapper.selectAllRulesByDeptId(deptId, type);
        if (list.size() <= 0) {
            this.initWarnRule(deptId, type);
            list = fseWarnRuleMapper.selectAllRulesByDeptId(deptId, type);
        }

        for (AppWarnRuleDTO warnMachSettingDTO : list) {
            Integer ruleId = warnMachSettingDTO.getRuleId();
            // 查找报警接收人和接收方式
            List<AppMsgToUserDTO> userList = fseWarnRuleUserMapper.selectByRuleId(ruleId);
            List<Integer> msgChannelList = fseWarnRuleChannelMapper.selectByRuleId(ruleId);
            warnMachSettingDTO.setUserList(userList);
            warnMachSettingDTO.setMsgChannelList(msgChannelList);
        }
        return new ListData<>(list);
    }

    @Override
    public void userAdd(FseWarnSetUserParam request) {
        logger.info("设置特种设备报警接收人及接收方式服务,param:{}", request.toString());
        List<Integer> ruleIdList = request.getRuleIdList();
        for (Integer ruleId : ruleIdList) {
            //消息联系人
            fseWarnRuleUserMapper.deleteLogicByRuleId(ruleId);
            List<AppMsgToUserDTO> userIdList = request.getUserList();
            if (userIdList != null && userIdList.size() > 0) {
                for (AppMsgToUserDTO warnUserDTO : userIdList) {
                    warnUserDTO.setRuleId(ruleId);
                }
                fseWarnRuleUserMapper.batchInsert(userIdList);
            }

            //消息渠道
            fseWarnRuleChannelMapper.deleteLogicByRuleId(ruleId);
            List<Integer> msgChannelList = request.getMsgChannelList();
            List<FseWarnRuleChannel> channelList = new ArrayList<>();
            for (Integer msgChannel : msgChannelList) {
                FseWarnRuleChannel appWarnRuleChannel = new FseWarnRuleChannel();
                appWarnRuleChannel.setMsgChannel(msgChannel);
                appWarnRuleChannel.setWarnRuleId(ruleId);
                channelList.add(appWarnRuleChannel);
            }
            if (!channelList.isEmpty()) {
                fseWarnRuleChannelMapper.batchInsert(channelList);
            }
        }

    }

    @Override
    public PageData<FseWarnRecordDTO> recordList(Integer deptId, Integer pageNum, Integer pageSize, Integer state, Integer ruleType, Integer type, Date startTime, Date endTime) {
        logger.info("特种设备报警记录服务,deptId:{},pageNum:{},pageSize:{},state:{},ruleType:{},startTime:{},endTime:{}",
                deptId, pageNum, pageSize, state, ruleType, startTime, endTime);
        // 时间处理
        if (endTime == null) {
            endTime = new Date();
        }
        if (startTime == null) {
            // 默认近30天的记录
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(endTime);
            calendar.add(Calendar.DAY_OF_MONTH, -30);
            startTime = calendar.getTime();
        }

        PageHelper.startPage(pageNum, pageSize);
        List<FseWarnRecordDTO> list = fseWarnMapper.selectByDeptId(Collections.singletonList(deptId),
                state, ruleType, type, startTime, endTime);
        PageHelper.clearPage();

        for (FseWarnRecordDTO fseWarnRecordDTO : list) {
            Integer ruleId = fseWarnRecordDTO.getRuleId();
            String triggerObjectIdStr = fseWarnRecordDTO.getTriggerObjectId();
            Integer triggerObjectId = Integer.parseInt(triggerObjectIdStr);
            FseWarnRule fseWarnRule = fseWarnRuleMapper.selectByPrimaryKey(ruleId);
            if (fseWarnRule == null) {
                continue;
            }
            Integer fseWarnRuleType = fseWarnRule.getType();
            fseWarnRecordDTO.setType(fseWarnRuleType);
            if (FseType.LIFT.getValue().equals(fseWarnRuleType)) {
                FseLift fseLift = fseLiftMapper.selectByPrimaryKey(triggerObjectId);
                if (fseLift == null) {
                    continue;
                }
                fseWarnRecordDTO.setCode(fseLift.getCode());
                String operators = fseLift.getOperators();
                List<FseOperatorDTO> operatorList = JSON.parseArray(operators, FseOperatorDTO.class);
                fseWarnRecordDTO.setOperatorList(operatorList);
            }
            if (FseType.CRANE.getValue().equals(fseWarnRuleType)) {
                FseCrane fseCrane = fseCraneMapper.selectByPrimaryKey(triggerObjectId);
                if (fseCrane == null) {
                    continue;
                }
                fseWarnRecordDTO.setCode(fseCrane.getCode());
                String operators = fseCrane.getOperators();
                List<FseOperatorDTO> operatorList = JSON.parseArray(operators, FseOperatorDTO.class);
                fseWarnRecordDTO.setOperatorList(operatorList);
            }
            if (FseType.GANTRY.getValue().equals(fseWarnRuleType)) {
                FseGantry fseGantry = fseGantryMapper.selectByPrimaryKey(triggerObjectId);
                if (fseGantry == null) {
                    continue;
                }
                fseWarnRecordDTO.setCode(fseGantry.getCode());
                String operators = fseGantry.getOperators();
                List<FseOperatorDTO> fseOperatorList = JSON.parseArray(operators, FseOperatorDTO.class);
                fseWarnRecordDTO.setOperatorList(fseOperatorList);
            }
            if (FseType.BRIDGE.getValue().equals(fseWarnRuleType)) {
                FseBridge fseBridge = fseBridgeMapper.selectByPrimaryKey(triggerObjectId);
                if (fseBridge == null) {
                    continue;
                }
                fseWarnRecordDTO.setCode(fseBridge.getCode());
                String operators = fseBridge.getOperators();
                List<FseOperatorDTO> fseOperatorList = JSON.parseArray(operators, FseOperatorDTO.class);
                fseWarnRecordDTO.setOperatorList(fseOperatorList);
            }
            if (FseType.CRAWLER.getValue().equals(fseWarnRuleType)) {
                FseCrawler fseCrawler = fseCrawlerMapper.selectByPrimaryKey(triggerObjectId);
                if (fseCrawler == null) {
                    continue;
                }
                fseWarnRecordDTO.setCode(fseCrawler.getCode());
                String operators = fseCrawler.getOperators();
                List<FseOperatorDTO> fseOperatorList = JSON.parseArray(operators, FseOperatorDTO.class);
                fseWarnRecordDTO.setOperatorList(fseOperatorList);
            }
        }
        return PageUtil.pageData(PageInfo.of(list));
    }

    @Override
    public List<FseWarnRecordDTO> recordList(List<Integer> deptIds, Integer state, Integer ruleType, Integer type, Date startTime, Date endTime) throws BizException {
        logger.info("获取特种设备报警记录,deptIds:{}, state:{}, ruleType:{}, type:{}, startTime:{}, endTime:{}",
                deptIds, state, ruleType, type, startTime, endTime);
        // 时间处理
        if (endTime == null) {
            endTime = new Date();
        }
        if (startTime == null) {
            // 默认近30天的记录
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(endTime);
            calendar.add(Calendar.DAY_OF_MONTH, -30);
            startTime = calendar.getTime();
        }
        return fseWarnMapper.selectByDeptId(deptIds, state, ruleType, type, startTime, endTime);
    }

    @Override
    public FseWarnDetailDTO recordDetail(Integer id) {
        logger.info("特种设备的报警详情服务,id:{}", id);
        FseWarnDetailDTO fseWarnDetailDTO = new FseWarnDetailDTO();
        FseWarn fseWarn = fseWarnMapper.selectByPrimaryKey(id);
        if (fseWarn == null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "未找到该报警记录");
        }
        BeanUtils.copyProperties(fseWarn, fseWarnDetailDTO);
        fseWarnDetailDTO.setHandleState(fseWarn.getState());

        Integer warnRuleId = fseWarn.getWarnRuleId();
        FseWarnRule fseWarnRule = fseWarnRuleMapper.selectByPrimaryKey(warnRuleId);
        if (fseWarnRule == null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "未找到该报警规则");
        }
        Integer type = fseWarnRule.getType();
        fseWarnDetailDTO.setType(type);

        // 查找设备信息
        String triggerObjectId = fseWarn.getTriggerObjectId();
        Integer fseId = Integer.parseInt(triggerObjectId);
        if (FseType.CRANE.getValue().equals(type)) {
            FseCrane fseCrane = fseCraneMapper.selectByPrimaryKey(fseId);
            if (fseCrane == null) {
                throw new BizException(ResultEnum.FAILURE.getCode(), "未找到该报警设备");
            }
            fseWarnDetailDTO.setCode(fseCrane.getCode());
            fseWarnDetailDTO.setModelName(fseCrane.getModelName());
            String operators = fseCrane.getOperators();
            List<FseOperatorDTO> operatorList = JSON.parseArray(operators, FseOperatorDTO.class);
            fseWarnDetailDTO.setOperatorList(operatorList);
        } else if (FseType.LIFT.getValue().equals(type)) {
            FseLift fseLift = fseLiftMapper.selectByPrimaryKey(fseId);
            if (fseLift == null) {
                throw new BizException(ResultEnum.FAILURE.getCode(), "未找到该报警设备");
            }
            fseWarnDetailDTO.setCode(fseLift.getCode());
            String operators = fseLift.getOperators();
            List<FseOperatorDTO> operatorList = JSON.parseArray(operators, FseOperatorDTO.class);
            fseWarnDetailDTO.setOperatorList(operatorList);
            fseWarnDetailDTO.setModelName(fseLift.getModelName());
        } else if (FseType.GANTRY.getValue().equals(type)) {
            FseGantry fseGantry = fseGantryMapper.selectByPrimaryKey(fseId);
            if (fseGantry == null) {
                throw new BizException(ResultEnum.FAILURE.getCode(), "未找到该报警设备");
            }
            fseWarnDetailDTO.setCode(fseGantry.getCode());
            String operators = fseGantry.getOperators();
            List<FseOperatorDTO> operatorList = JSON.parseArray(operators, FseOperatorDTO.class);
            fseWarnDetailDTO.setOperatorList(operatorList);
            fseWarnDetailDTO.setModelName(fseGantry.getModelName());
        } else if (FseType.BRIDGE.getValue().equals(type)) {
            FseBridge fseBridge = fseBridgeMapper.selectByPrimaryKey(fseId);
            if (fseBridge == null) {
                throw new BizException(ResultEnum.FAILURE.getCode(), "未找到该报警设备");
            }
            fseWarnDetailDTO.setCode(fseBridge.getCode());
            String operators = fseBridge.getOperators();
            List<FseOperatorDTO> fseOperatorList = JSON.parseArray(operators, FseOperatorDTO.class);
            fseWarnDetailDTO.setOperatorList(fseOperatorList);
            fseWarnDetailDTO.setModelName(fseBridge.getModelName());
        } else if (FseType.CRAWLER.getValue().equals(type)) {
            FseCrawler fseCrawler = fseCrawlerMapper.selectByPrimaryKey(fseId);
            if (fseCrawler == null) {
                throw new BizException(ResultEnum.FAILURE.getCode(), "未找到该报警设备");
            }
            fseWarnDetailDTO.setCode(fseCrawler.getCode());
            fseWarnDetailDTO.setModelName(fseCrawler.getModelName());
            String operators = fseCrawler.getOperators();
            List<FseOperatorDTO> fseOperatorList = JSON.parseArray(operators, FseOperatorDTO.class);
            fseWarnDetailDTO.setOperatorList(fseOperatorList);
        }

        return fseWarnDetailDTO;
    }

    @Override
    public void recordHandle(SysUser user, AppWarnHandleParam request) {
        logger.info("处理特种设备报警服务,param:{}", request.toString());
        Integer warnId = request.getWarnId();
        String handleRemark = request.getHandleRemark();
        String handleResult = request.getHandleResult();

        FseWarn record = new FseWarn();
        record.setHandleTime(new Date());
        record.setHandleRemark(handleRemark);
        record.setHandleResult(handleResult);
        record.setHandleUserId(user.getId());
        record.setHandleUserName(user.getUsername());
        record.setHandleUserPhone(user.getPhone());
        record.setState(HandleFlag.HANDLE.getValue());
        record.setId(warnId);
        fseWarnMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public void batchHandle(WarnBatchHandleParam param) throws BizException {
        logger.info("批量处理特种设备报警记录服务,param:{}", param.toString());
        List<Integer> warnIdList = param.getWarnIdList();
        String handleResult = param.getHandleResult();
        String handleRemark = param.getHandleRemark();
        Integer userId = param.getUserId();
        String userName = param.getUserName();
        String phone = param.getPhone();
        fseWarnMapper.batchUpdateState(warnIdList, handleResult, handleRemark, userId, userName, phone);
    }

    @Override
    public void del(WarnBatchDelParam param) throws BizException {
        logger.info("批量删除特种设备报警记录服务,param:{}", param.toString());
        fseWarnMapper.deleteLogic(param.getWarnIdList());
    }

    @Override
    public Integer getWarnNum(List<Integer> deptIds, Date startTime, Date endTime) {
        logger.info("查询时间内报警数服务,deptId:{},startTime:{},endTime:{}", deptIds, startTime, endTime);
        return fseWarnMapper.countWarnNum(deptIds, null, null, startTime, endTime);
    }

    @Override
    public Integer getWarnNum(List<Integer> deptIds, Integer type, Date startTime, Date endTime) throws BizException {
        logger.info("查询时间内报警数服务,deptId:{},type:{},startTime:{},endTime:{}", deptIds, type, startTime, endTime);
        return fseWarnMapper.countWarnNum(deptIds, type, null, startTime, endTime);
    }

    @Override
    public Integer getWarnNum(List<Integer> deptIds, Integer type, Integer ruleType, Date startTime, Date endTime) throws BizException {
        logger.info("查询时间内报警数服务, deptId:{}, type:{}, ruleType:{}, startTime:{}, endTime:{}",
                deptIds, type, ruleType, startTime, endTime);
        return fseWarnMapper.countWarnNum(deptIds, type, ruleType, startTime, endTime);
    }

    @Override
    public FseCraneWarnCountDTO getCraneWarnCount(Integer craneId, Date startTime, Date endTime) throws BizException {
        List<FseWarnCountDTO> list = fseWarnMapper.countCraneWarn(craneId, startTime, endTime);
        FseCraneWarnCountDTO warnCountDTO = new FseCraneWarnCountDTO();
        int total = 0;
        if (list != null && !list.isEmpty()) {
            for (FseWarnCountDTO fseWarnCountDTO : list) {
                total += fseWarnCountDTO.getCount();
            }
        }
        warnCountDTO.setTotal(total);
        if (total > 0) {
            warnCountDTO.setWarnList(list);
        }
        return warnCountDTO;
    }

    private void initWarnRule(Integer deptId, Integer type) {
        List<FseWarnRule> list = new ArrayList<>();
        FseWarnRuleType[] warnRuleTypes = FseWarnRuleType.values();
        for (FseWarnRuleType warnRuleType : warnRuleTypes) {
            if (warnRuleType.type().equals(type)) {
                FseWarnRule record = new FseWarnRule();
                record.setDeptId(deptId);
                record.setName(warnRuleType.tittle());
                record.setRuleType(warnRuleType.value());
                record.setType(warnRuleType.type());
                list.add(record);
            }
        }
        if (list.size() > 0) {
            fseWarnRuleMapper.batchInsert(list);
        }
    }
}

